package com.wzapp.sitposture.setup.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.wzapp.sitposture.common.ipdb.CityInfo;
import com.wzapp.sitposture.common.util.AddressUtil;
import com.wzapp.sitposture.common.util.IPAddressUtil;
import com.wzapp.sitposture.common.util.ToolUtil;
import com.wzapp.sitposture.config.redis.service.RedisService;
import com.wzapp.sitposture.setup.entity.City;
import com.wzapp.sitposture.setup.entity.Setup;
import com.wzapp.sitposture.setup.repository.CityRepository;
import com.wzapp.sitposture.setup.repository.SetupRepository;
import com.wzapp.sitposture.setup.service.SetupService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * Created by qianglong on 2018/1/16.
 */
@Slf4j
@Service
public class SetupServiceImpl implements SetupService {

    @Autowired
    SetupRepository setupRepository;

    @Autowired
    CityRepository cityRepository;

    @Autowired
    RedisService redisService;

    private final String STATUS_VALID = "valid";

    @Value("${ql.version}")
    private String defaultVersion;

    @Override
    public List<City> findCitiesByVersion(String version) {
        return cityRepository.findCitiesByVersionLessThanEqual(version);
    }

    @Override
    public String findCityById(String id) {

        City city = cityRepository.findOne(id);
        if (city != null) {
            return city.getCity();
        }
        return null;
    }

    @Override
    public String findFullCityNameById(String id) {
        if (ToolUtil.isNotEmpty(id)) {
            City city = cityRepository.findOne(id);
            if (city != null) {
                return city.getProvince() + "." + city.getCity();
            }
        }
        return null;
    }

    @Override
    @Cacheable(value = "getCityId", key = "#cityName", condition = "#cityName != null")
    public String getCityId(String cityName) {
        if (ToolUtil.isEmpty(cityName)) {
            return null;
        }
        String[] items = cityName.split(" ");
        City city = null;
        if (items.length == 2) {
            city = cityRepository.findTop1ByProvinceStartingWithAndCityStartingWith(items[0], items[1]);
        } else {
            city = cityRepository.findTop1ByCityStartingWith(items[0]);
        }
        if (ToolUtil.isNotEmpty(city)) {
            return city.getId();
        }
        return null;
    }

    @Override
    public List<Setup> findByGroupType(String groupType, String version) {

        return setupRepository.findByGroupTypeAndVersionAndStatusOrderBySortNum(groupType, version,STATUS_VALID);
    }

    @Override
    public List<City> findProvince() {

        return cityRepository.findProvince();
    }

    @Override
    public List<City> findCitiesByProvinceCode(String provinceCode) {

        return cityRepository.findCitiesByProvinceCodeOrderBySortNum(provinceCode);
    }

    @Override
    public JSONObject findCityInfo() {

        // 接收到请求，记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        String ip = IPAddressUtil.getClientIpAddress(request);

        String city = null;
        String cityId = null;
        Object cityObj = redisService.get(ip);
        if (null != cityObj) {
            city = (String) cityObj;
        }
        if (null==city){
            try {
                com.wzapp.sitposture.common.ipdb.City db = new com.wzapp.sitposture.common.ipdb.City("/opt/servers/eig-1.0/ipdb/ip.ipdb");
                CityInfo info = db.findInfo(ip, "CN");
                city=info.getCityName().trim();
                log.info("从ipdb 中获取ip成功====="+city);
            } catch (Exception e) {
                log.error("从ipdb 中获取ip错误=====",e);
            }
        }

        if (null == city) {
            city = AddressUtil.getAddressFromToolIp(ip);
        }
        if (null == city) {
            city = AddressUtil.getAddressByTaoBao("ip=" + ip, "utf-8");
        }
        //126准确性最差
        if (null == city) {
            city = AddressUtil.getAddressBy126(ip);
        }

        if(null == city){
            //TODO 如果都查询不到设置一个默认值
            city = "南京";
        }
        if (null != city) {
            //设置ip城市缓存(缓解淘宝不可用问题)，淘宝城市解析限制10qps(query per second)
            //modify by ql 1小时后过期
            redisService.set(ip, city, 3600L);
            cityId = this.getCityId(city);
        }

        JSONObject result = new JSONObject();
        result.put("city", city);
        result.put("cityId", null == cityId ? "" : cityId);
        log.debug("===============findCityInfo===============" + result.toJSONString());
        return result;
    }

    @Override
    public JSONObject findOneByGroupType(String groupType) {

        Setup setup = setupRepository.findTop1ByGroupType(groupType);
        if (null != setup) {
            return setup.getData();
        }
        return null;
    }

    @Override
    public Setup findOneById(String id) {

        Setup setup = setupRepository.findOne(id);

        return setup;
    }

    @Override
    public boolean getSwitch(String groupType) {

        JSONObject jsonObject = this.findOneByGroupType(groupType);
        if(null != jsonObject){
            return jsonObject.getBooleanValue("value");
        }
        return false;
    }
}
